package org.duang.db.mongo.parser.encode;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.duang.db.annotation.VoColl;
import org.duang.db.mongo.parser.EncodeConvetor;
import org.duang.kit.ToolsKit;

import com.mongodb.DBObject;

/**
 * Vo集合对象属性转换
 * @author laotang
 */
public class VoCollEncoder extends Encoder {

	public VoCollEncoder( Object value, Field field ) {
		super(value, field);
	}

	@Override
	public String getFieldName() {
		String fieldName = field.getAnnotation(VoColl.class).name();
		return (ToolsKit.isNotEmpty(fieldName)) ? fieldName : field.getName();
	}

	@Override
	public Object getValue() {
		Object result = null;
		Class<?> fieldType = field.getType();
		if(fieldType.isArray()){
			result = encodeArray();
		} else {
			ParameterizedType paramType = (ParameterizedType)field.getGenericType();
			Type[] paramTypes = paramType.getActualTypeArguments();
			if(paramTypes.length == 1) {
				result = encodeCollection();
			} else if (paramTypes.length == 2){
				result = encodeMap();
			}
		}
		return result;
	}

	private Object encodeArray(){
		int length = Array.getLength(value);
		List<DBObject> result = new ArrayList<DBObject>(length);
		for (int i = 0; i < length; i++) {
			Object obj = Array.get(value, i);
			if(null != obj){
				result.add(EncodeConvetor.convetor(obj));
			}
		}
		return result;
	}
	
	@SuppressWarnings("unchecked")
	private Object encodeCollection(){
		List<DBObject> result = new ArrayList<DBObject>();
		Collection coll = (Collection)value;
		if(null != coll){
			for(Iterator it = coll.iterator(); it.hasNext();){
				Object obj = it.next();
				if(ToolsKit.isNotEmpty(obj)){
					result.add(EncodeConvetor.convetor(obj));
				}
			}
		}
		return result;
	}
	
	@SuppressWarnings("unchecked")
	private Object encodeMap(){
		Map map = (Map)value;
		Map result = new HashMap(map.size());
		for(Iterator<String> it = map.keySet().iterator(); it.hasNext();){
			String key = it.next();
			Object obj = map.get(key);
			if(ToolsKit.isNotEmpty(obj)){
				result.put(key, EncodeConvetor.convetor(obj));
			} else {
				result.put(key, null);
			}
		}
		return result;
	}
	
}
